package com.coder520.sync_learning.demo.threadPool;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

import com.coder520.sync_learning.demo.ShutDown;

public class DefultThreadPool<Job extends Runnable> implements ThreadPool<Job>{
//	最大的限制数
	private static final int MAX_WORKER_NUMBERS=10;
//	默认连接数
	private static final int DEFULT_WORKER_NUMBERS=5;
//	最小连接数
	private static final int MIN_WORKER_NUMBERS=1;
	
//	这是一个工作列表，将会向里面插入工作
	private final LinkedList<Job> jobs=new LinkedList<Job>();
	
//	工作者列表
	private final List<Worker> workers=Collections.synchronizedList(new ArrayList<Worker>());
	
//	工作者线程的数量
	private int workerNum=DEFULT_WORKER_NUMBERS;
	
//	线程编号生成
	private AtomicLong threadNum=new AtomicLong();
	
	public DefultThreadPool() {
		// TODO Auto-generated constructor stub
		initializedWorkers(DEFULT_WORKER_NUMBERS);
	}
	
	public DefultThreadPool(int num){
		workerNum=num>MAX_WORKER_NUMBERS?MAX_WORKER_NUMBERS:num<MIN_WORKER_NUMBERS?MIN_WORKER_NUMBERS:num;
		initializedWorkers(workerNum);
	}
	
	/**
	 * 初始化线程工作者数量
	 * 
	 * @param defultWorkerNumbers
	 *	2018年6月11日
	 */
	private void initializedWorkers(int num) {
		// TODO Auto-generated method stub
		for (int i = 0; i < num; i++) {
			Worker worker=new Worker();
			workers.add(worker);
			Thread thread=new Thread(worker,"ThreadPool-Worker-"+threadNum.incrementAndGet());
			thread.start();
		}
		
	}

	
	@Override
	public void execute(Job job) {
		// TODO Auto-generated method stub
		if (job!=null) {
			synchronized (jobs) {
				jobs.addLast(job);
				jobs.notify();
			}
		}
	}

	@Override
	public void shutDown() {
		// TODO Auto-generated method stub
		for (Worker worker : workers) {
			worker.shutDown();
			
		}
	}

	@Override
	public void addWorker(int num) {
		// TODO Auto-generated method stub
		synchronized (jobs) {
//			限制新增的workers数量不能超过最大值
			if (num+this.workerNum>MAX_WORKER_NUMBERS) {
				num=MAX_WORKER_NUMBERS;
			}
			
			initializedWorkers(num);
			
			this.workerNum+=num;
			
		}
	}

	@Override
	public void removeWorker(int num) {
		// TODO Auto-generated method stub
		synchronized (jobs) {
			if (num>=this.workerNum) {
				throw 	new IllegalArgumentException("beyond  workNum");
			}
			
//			按照给定的数量停止Worker
			int count=0;
			while(count<num) {
				Worker worker=workers.get(count);
				if (workers.remove(worker)) {
					worker.shutDown();
						count++;
				}
			}
			
			this.workerNum-=count;
		}
	}

	@Override
	public int getJobSize() {
		// TODO Auto-generated method stub
		return jobs.size();
	}
	class Worker implements Runnable{
		private volatile boolean running=true;
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			while (running) {
				Job job=null;
				synchronized (jobs) {
//					如果工作者列表是空的那么就wait
					while(jobs.isEmpty()) {
						try {
							jobs.wait();
						} catch (Exception e) {
							// TODO: handle exception
//							感知到	外部对WorkerThread的中断操作，返回
							Thread.currentThread().interrupt();
							return;
						}
					}
					
//					取出一个job
					job=jobs.removeFirst();
				}
				
				if (job!=null) {
					try {
						job.run();
					} catch (Exception e) {
						// TODO: handle exception
					}
					
				}
			}
		}

		public void shutDown() {
			// TODO Auto-generated method stub
			running=false;
		}
		
	}
	
}
